//-----------------------------------------------------------------------------
// Dynamic weather - all about rain/snow Vertex Shader
//-----------------------------------------------------------------------------

#include "DynamicWeatherCommon.hlsl"


#define PARTICLE_BOX 30.0f

	uniform float4x4 g_mWorldViewProjPrev;
	
	uniform float4	g_vPositionOffset;
	uniform float4	g_vVelocity;
	uniform float4	g_vAlpha;
	
	uniform float4	g_vViewPosition;
	uniform float4	g_vSizeScale;
	uniform float4	g_vLighting;	
	
	uniform float4	g_vForward;	
	

	VSOUT ProcessVertex( VSIN _input )
	{
		VSOUT Output = (VSOUT)0;
		
		Output.UV = _input.TexCoord0;
		
		float3 position = _input.Position;
		
		// now the position is in [0, PARTICLE_BOX]
		position -= g_vPositionOffset.xyz;
		position = fmod(position.xyz, float3( PARTICLE_BOX, PARTICLE_BOX, PARTICLE_BOX ));
		
		position += g_vForward.xyz - float3(PARTICLE_BOX/2, PARTICLE_BOX/2, PARTICLE_BOX/2);
		
		// color based on distance from origin
		float subtractcolor = length(position.xyz) / PARTICLE_BOX;
		float distanceColorScale = 1 - subtractcolor * subtractcolor;
		
		float4 worldPosBottom = float4(position.xyz + g_vViewPosition.xyz, 1.0f);
		float4 worldPosTop = float4(worldPosBottom.xyz + g_vVelocity.xyz * g_vSizeScale.y, 1.0f);
		
		float4 bottom = mul(worldPosBottom, g_mWorldViewProj);
		float4 top = mul(worldPosTop, g_mWorldViewProj);
		float4 topprev = mul(worldPosTop, g_mWorldViewProjPrev);
		
		float2 dir = (top.xy / top.w) - (bottom.xy / bottom.w);
		float2 dirprev = (topprev.xy / topprev.w) - (bottom.xy / bottom.w);
		
		float lenColorScale = saturate( length(dir) / length(dirprev) );
		
		float2 dirPerp = normalize(float2(-dirprev.y, dirprev.x));
		
		Output.Position = lerp( topprev, bottom, _input.TexCoord0.y );
		
		Output.Position.xy += (0.5f - _input.TexCoord0.x) * dirPerp * g_vSizeScale.x;
		
		Output.color = g_vLighting * distanceColorScale * lenColorScale * g_vAlpha.x;
		
		Output.WorldPosition = worldPosBottom.xyz;
		
		return Output;
	}